
#include "ContactManager.h"

ContactManager::ContactManager(const wxString& home) 
	: homePath(home), contactConfig(0), contactExConfig(0)
{
    contactConfig = new wxFileConfig(wxEmptyString, wxEmptyString, homePath + _T("/contacts.sync"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_RELATIVE_PATH);
    contactExConfig = new wxFileConfig(wxEmptyString, wxEmptyString, homePath + _T("/contacts.local"), wxEmptyString, wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_RELATIVE_PATH);
}

ContactManager::~ContactManager()
{
	//todo delete all the contacts
	for(GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it){
        MsnGroup* group = *it;
        delete group;
    }

    for(ContactMap::iterator it = contactMap.begin(); it != contactMap.end(); ++it){
        MsnContact* contact = it->second;
        delete contact;
    }

	wxDELETE(contactConfig);
	wxDELETE(contactExConfig);

	DEBUG(_T("~ContactManager"));
}

void ContactManager::LoadContact()
{
    wxString str;
    long dummy;

	bool b = contactConfig->GetFirstEntry(str, dummy);
    while ( b ) {
        wxString groupName =str;
        wxString groupID = contactConfig->Read(str);
        AddGroup(new MsnGroup(groupID, groupName));

        b = contactConfig->GetNextEntry(str, dummy);
    }

    b = contactConfig->GetFirstGroup(str, dummy);
    while ( b ) {
        MsnContact* contact = new MsnContact();
        contact->SetPassport(str);
        contact->SetID(contactConfig->Read(str+_T("/id")));
        contact->SetName(contactConfig->Read(str+_T("/name")));
        contact->SetGroupString(contactConfig->Read(str+_T("/group")));
        int list = 0;
        contactConfig->Read(str+_T("/list"), &list);
        contact->SetListNumber(list);
        contact->SetStatus(wxEmptyString);
        //wxMessageBox(_T("load ")+contact->GetPassport());

        AddContact(contact);

        //MsnMessenger::Get()->ContactListed(contact);

        b = contactConfig->GetNextGroup(str, dummy);
   }
}

void ContactManager::SaveContact()
{
	wxDELETE(contactConfig);

    wxString filePath = homePath + _T("/contacts.sync");
    wxRemoveFile(filePath);

    contactConfig = new wxFileConfig(wxEmptyString, wxEmptyString, filePath, wxEmptyString, wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_RELATIVE_PATH);

	for(GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it){
        MsnGroup* group = *it;
        contactConfig->Write(group->GetName(),group->GetID());
    }

    for(ContactMap::iterator it = contactMap.begin(); it != contactMap.end(); ++it){
        MsnContact* contact = it->second;
        wxString passport = contact->GetPassport();
        contactConfig->Write(passport+_T("/id"),contact->GetID());
        contactConfig->Write(passport+_T("/name"),contact->GetName());
        contactConfig->Write(passport+_T("/group"),contact->GetGroupString());
        contactConfig->Write(passport+_T("/list"),contact->GetListNumber());
    }

    contactConfig->Flush();
}

void ContactManager::LoadContactEx()
{
    wxString passport;
    long dummy;

    bool b = contactExConfig->GetFirstGroup(passport, dummy);
    while ( b ) {
		wxString name = contactExConfig->Read(passport+_T("/name"));
        wxString nickname = contactExConfig->Read(passport+_T("/nickname"));

		if(contactMap.find(passport) != contactMap.end()){
			MsnContact* contact = contactMap[passport];
			contact->SetName(name);
            contact->SetNickname(nickname);
			DEBUG(_T("load name: ")+name+_T(" and nickname: ")+nickname);
        }

        b = contactExConfig->GetNextGroup(passport, dummy);
   }
}

void ContactManager::SaveContactEx()
{
    for(ContactMap::iterator it = contactMap.begin(); it != contactMap.end(); ++it){
        MsnContact* contact = it->second;
        wxString passport = contact->GetPassport();
		contactConfig->Write(passport+_T("/name"),contact->GetName());
        contactConfig->Write(passport+_T("/nickname"),contact->GetNickname());
    }

    contactExConfig->Flush();
}

void ContactManager::Reset()
{
    groupList.clear();
    contactMap.clear();
}

void ContactManager::AddContact(MsnContact* contact)
{
    MsnContact* oldContact = contactMap[contact->GetPassport()];
    contactMap[contact->GetPassport()] = contact;

	if(oldContact){
        delete oldContact;
	}
}

void ContactManager::AddContactToGroup(const wxString& contactID, const wxString& groupID)
{
	MsnContact* contact = GetContactByID(contactID);
	if(contact != NULL){
		DEBUG(_T("add contact ")+ contact->GetPassport() + _T(" to ") + groupID);
        contact->AddGroup(groupID);
	}	
}


MsnContact* ContactManager::GetContact(const wxString& passport)
{
    return contactMap[passport] ;
}

MsnContact* ContactManager::GetContactByID(const wxString& contactID)
{
    for(ContactMap::iterator it = contactMap.begin(); it != contactMap.end(); ++it){
        MsnContact* contact = it->second;
        if(contactID.IsSameAs(contact->GetID()))
            return contact;
    }

    return NULL;
}

void ContactManager::RemoveContact(const wxString& contactID)
{
	MsnContact* contact = GetContactByID(contactID);
	if(contact != NULL){
		DEBUG(_T("remove contact ")+ contact->GetPassport());
		contactMap.erase(contact->GetPassport());
        delete contact;
	}
}

void ContactManager::RemoveContactFromGroup(const wxString& contactID, const wxString& groupID)
{
	MsnContact* contact = GetContactByID(contactID);
	if(contact != NULL){
		DEBUG(_T("remove contact ")+ contact->GetPassport() + _T(" from ") + groupID);
        contact->RemoveGroup(groupID);
	}
}

void ContactManager::UpdateContactStatus(const wxString& passport, const wxString& status)
{
    MsnContact* contact = GetContact(passport);
    if(contact){
        contact->SetStatus(status);
    }
}

void ContactManager::UpdateContactNickname(const wxString& passport, const wxString& nickname)
{
    MsnContact* contact = GetContact(passport);
    if(contact){
        if(!nickname.IsSameAs(contact->GetNickname())){
            contact->SetNickname(nickname);
            contactExConfig->Write(passport+_T("/nickname"),nickname);
            contactExConfig->Flush();
        }
    }
}

void ContactManager::UpdateContactName(const wxString& passport, const wxString& name)
{
    MsnContact* contact = GetContact(passport);
    if(contact){
        if(!name.IsSameAs(contact->GetName())){
            contact->SetName(name);
            contactConfig->Write(passport+_T("/name"), name);
            contactConfig->Flush();
			contactExConfig->Write(passport+_T("/name"), name);
            contactExConfig->Flush();
        }
    }
}

bool less_second(MsnGroup* m1, MsnGroup* m2) {
    return m1->GetName().Cmp(m2->GetName())<0;
}

void ContactManager::AddGroup(MsnGroup* group)
{
    groupList.push_back(group);
    sort(groupList.begin(), groupList.end(), less_second);

	//contactConfig->Write(group->GetName(),group->GetID());
	//contactConfig->Flush();
}

MsnGroup* ContactManager::GetGroup(const wxString& id)
{
    for(GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it){
        if(id.IsSameAs((*it)->GetID()))
            return *it;
    }

    return NULL;
}

void ContactManager::DeleteGroup(const wxString& id)
{
    for(GroupList::iterator it = groupList.begin(); it != groupList.end();  ++it){
        if(id.IsSameAs((*it)->GetID())){
			MsnGroup* group = *it;
            groupList.erase(it);
            delete group;
			return;
        }
    }

    //contactConfig.DeleteEntry(_T("group.")+id);
    //contactConfig.Flush();
}

void ContactManager::UpdateGroupName(const wxString& id, const wxString& name)
{
    for(GroupList::iterator it = groupList.begin(); it != groupList.end(); ++it){
        if(id.IsSameAs((*it)->GetID())){
            (*it)->SetName(name);
            return;
        }
    }
}

void ContactManager::AddRecentContact(const wxString& contact)
{
    recentList.Remove(contact);
    recentList.Insert(contact, 0);

    if(recentList.GetCount() > 10){
        recentList.RemoveAt(10, recentList.GetCount()-10);
    }
}

wxArrayString ContactManager::GetOnlineContactList()
{
    wxArrayString contactList;
    for(ContactMap::iterator it = contactMap.begin(); it!= contactMap.end(); ++it){
        MsnContact* contact = it->second;
        if(contact->IsOnline()){
            contactList.Add(contact->GetPassport());
        }
    }
    return contactList;
}
